home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Collection of Tools & Utilities
/
Collection of Tools and Utilities.iso
/
asmutil
/
asm_n_z.zip
/
SPY'.ASM
< prev
next >
Wrap
Assembly Source File
|
1987-05-11
|
17KB
|
430 lines
name spyprime
rt equ 0dh ; return
lf equ 0ah ; linefeed
eof equ 1ah ; end of file
ok_seg equ 1 ; flag for segment decode check
ok_off equ 2 ; flag for offset decode check
max_size equ 4095 ; maximum size for SPY' search region
beep_delay equ 4 ; number of clock ticks between beeps
timer_count equ 597 ; frequency of beep = 1,193,180 / timer_count
; These constants are used by the newint16h routine in this, the SPY' program.
; They are not needed for the SPY program.
ckey1 equ 20cdh ; value of first key (a "backwords" int 20)
ckey2 equ 1234h ; value of second key
ckey3 equ 5678h ; value of third key
code segment
assume cs:code, ds:code
org 0
key1 dw ? ; offset of int 20h instruction
; used to verify a PSP location
org 100h
begin: jmp start ; jump to program start location
;-------------------------------------------------------------------------------
; This copyright message appears when SPY'.COM is "typed" to the screen.
;-------------------------------------------------------------------------------
db 8,8,8,' '
copyright db rt,lf
db "SPY' Copyright (C) 1987 by Charles Lazo III, v1.0"
db eof,8,' ',rt,lf,'$'
key2 dw ckey2 ; keys used to determine prior load of SPY'
key3 dw ckey3
oldint8 dd ? ; double word storage for old int 8 vector
oldint16h dd ? ; double word storage for old int 16 vector
beeps dw 0 ; number of beeps (notices) to send to user
delay dw 1 ; number of clock ticks 'til next beep
beep_on db 0 ; beep on/off status
spy_size dw ? ; number of bytes to spy on
resident db 0 ; indicates prior load of SPY' (0 = none)
spy_location label dword
spy_off dw ? ; storage for value of offset for SPYing
spy_seg dw ? ; storage for value of segment for SPYing
;-------------------------------------------------------------------------------
; Comparisons of the spied region and the spy buffer (set up initially as a copy
; of the spied region) are made in this addition to the clock interrupt.
; Changes to the spied region are counted and the spy buffer is updated. The
; speaker is turned on and off here, but frequency is set during program
; initialization.
;-------------------------------------------------------------------------------
newint8 proc near
push ax ; save interrupted program's registers
push bx
push cx
push si
push di
push ds
push es
mov ax,cs ; our data lies here
mov ds,ax
lea si,spy_buffer ; point to our buffer
les di,spy_location ; point to spied region
mov cx,spy_size ; compare whole region
cld ; forward!
cmp_more: repz cmpsb ; compare until no match or cx = 0
jz cmp_done ; if zero, then cx = 0 and we're done
inc beeps ; account for a change
mov al,es:[di-1] ; change accounted; update spy_buffer
mov [si-1],al
or cx,cx ; set zero flag by cx (avoid inf loop)
jmp short cmp_more ; continue 'til done
cmp_done: cmp beep_on,0 ; is the beep on?
jz do_beep? ; no, shall we do a beep?
dec beep_on ; yes, turn it off
in al,97 ; get speaker control bits
and al,0fch ; set them off
out 97,al ; turn off speaker
jmp short exit ; job done; get out
do_beep?: cmp beeps,0 ; are there beeps to be done?
jz delay1 ; no, get out
dec delay ; reduce delay 'til next beep
jnz exit ; not zero, then exit
in al,97 ; get speaker control bits
or al,3 ; set them on
out 97,al ; turn on speaker
inc beep_on ; signal beep is on
mov delay,beep_delay; reinitialize delay counter
dec beeps ; one less beep to do
jmp short exit ; leave now
delay1: mov delay,1 ; don't wait for first beep of a series
exit: pop es ; restore registers
pop ds
pop di
pop si
pop cx
pop bx
pop ax
jmp dword ptr cs:oldint8 ; continue with interrupt
newint8 endp
;-------------------------------------------------------------------------------
; Keyboard interrupt, int 16h, is issued with function number ah = 77h in the
; set_es routine. If there has been no prior load of SPY', then the interrupt
; returns without changing anything. However, if SPY' has been run previously,
; then this routine has been chained into the interrupt 16h handler and the
; issue of "keyboard" function number 77h causes the returned value of es to be
; what cs was for the original load of SPY'.
;-------------------------------------------------------------------------------
newint16h proc near
cmp ah,77h ; our cue?
jne not_us ; nah, not us
push ax ; save this
mov ax,ckey1 ; have we a match for the first key?
cmp ax,cs:key1
je test_2nd ; yes, test the 2nd key
jmp short onward ; no previous load found
test_2nd: mov ax,ckey2 ; have we a match for the second key?
cmp ax,cs:key2
je test_3rd ; yes, test the 3rd key
jmp short onward ; no previous load found
test_3rd: mov ax,ckey3 ; have we a match for the third key?
cmp ax,cs:key3
jne onward ; no match => no previous load
pop ax ; unstack saved value
mov ax,cs ; pass this cs in es
mov es,ax
mov ax,ckey1 ; pass these to inform set_es
mov bx,ckey2
iret
onward: pop ax ; recover this
not_us: jmp dword ptr cs:oldint16h ; continue with interrupt
newint16h endp
;-------------------------------------------------------------------------------
; Here the region spied upon is copied to an area of the TSR that remains in
; memory after termination, the spy_buffer. The es register is equal either to
; cs if SPY' has not yet been loaded or to the value of cs when SPY' was loaded
; previously (accomplished by a call to the set_es routine).
;-------------------------------------------------------------------------------
copy_spied: lea di,spy_buffer ; destination of copy
mov si,spy_off ; the offset is source of copy
mov cx,spy_size ; number of bytes to copy
mov ax,spy_seg ; load segment of SPY' region to ds
push ds ; SOD (save our data)
mov ds,ax
cld ; forward copy
rep movsb ; copy the SPY' region to spy_buffer
pop ds ; RestoreOD
cmp resident,0 ; is SPY' currently resident in memory?
je tsr ; no, make it so
mov ax,4c00h ; yes, end with error code 0
int 21h
;-------------------------------------------------------------------------------
; SPY' has not yet been loaded into memory, so we do it now. First the 8253-5
; chip that generates the frequency of the beeps is initialized with the value
; given by the constant timer_count. Then the new interrupt 8 routine is
; spliced in and finally the constant max_size is used to reserve enough memory
; for the largest permissible spy buffer.
;-------------------------------------------------------------------------------
tsr: mov delay,beep_delay; initialize delay counter
; set 8253-5 programmable timer to chosen frequency
mov al,182 ; byte to initialize 8253 timer
out 67,al ; tell timer next two bytes are count
mov ax,timer_count ; get timer count
out 66,al ; output low byte
mov al,ah
out 66,al ; output high byte
mov ax,3508h ; get the interrupt 8 (clock) vector
int 21h ; with DOS function 35h call
; Retain offset and segment of interrupt 8 vector:
mov word ptr cs:oldint8,bx
mov word ptr cs:oldint8+2,es
lea dx,newint8 ; place offset in dx
mov ax,2508h ; set its pointer into interrupt table
int 21h ; with DOS function 25h call
mov ax,3516h ; get the int 16h (keyboard) vector
int 21h ; with DOS function 35h call
; Retain offset and segment of interrupt 16h vector:
mov word ptr cs:oldint16h,bx
mov word ptr cs:oldint16h+2,es
lea dx,newint16h ; place offset in dx
mov ax,2516h ; set its pointer into interrupt table
int 21h ; with DOS function 25h call
lea dx,spy_buffer ; where SPY' buffer begins
mov cx,max_size ; add the maximum size of the buffer:
add dx,cx
mov cl,4 ; compute number of paragraphs to save:
shr dx,cl ; bytes to paragraphs in dx
inc dx ; insure sufficient size for buffer
mov ax,3100h ; terminate but stay resident code = 0
int 21h
;---------------------------------------------------------